package cn.itcast.service.cargo.impl;

import cn.itcast.dao.cargo.ExportDao;
import cn.itcast.dao.cargo.ExportProductDao;
import cn.itcast.dao.cargo.PackingDao;
import cn.itcast.domain.cargo.*;
import cn.itcast.service.cargo.PackingService;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
import java.util.stream.Collectors;

@Service(timeout = 100000)
public class PackingServiceImpl implements PackingService {
    @Autowired
    private PackingDao packingDao;
    @Autowired
    private ExportDao exportDao;
    @Autowired
    private ExportProductDao exportProductDao;

    /**
     * 进行装箱
     *
     * @param exportIds
     * @return
     */
    @Override
    public Packing toAddPacking(String exportIds) {
        String[] exportStringArray = exportIds.split(",");
        Packing packing = new Packing();
        if (exportStringArray.length > 0) {
            List<String> exportIdList = Arrays.asList(exportStringArray);
            ExportExample exportExample = new ExportExample();
            exportExample.createCriteria().andIdIn(exportIdList);
            List<Export> exports = exportDao.selectByExample(exportExample);
            //定义总体积、总净重、总毛重和装箱费用的变量
            double totalVolume = 0;
            double totalNetWeight = 0;
            double totalGrossWeight = 0;
            //合同字符串
            StringBuilder contractNos = new StringBuilder("");
            if (exports != null && exports.size() > 0) {
                for (Export export : exports) {
                    if (export.getGrossWeights() != null) {
                        totalGrossWeight += export.getGrossWeights();
                    }
                    if (export.getMeasurements() != null) {
                        totalVolume += export.getMeasurements();
                    }
                    //计算总净重
                    ExportProductExample exportProductExample = new ExportProductExample();
                    exportProductExample.createCriteria().andExportIdIn(exportIdList);
                    List<ExportProduct> exportProducts = exportProductDao.selectByExample(exportProductExample);
                    if (exportProducts != null && exportProducts.size() > 0) {
                        for (ExportProduct exportProduct : exportProducts) {
                            if (exportProduct.getNetWeight() != null) {
                                totalNetWeight += exportProduct.getNetWeight();
                            }
                        }
                    }
                    //封装合同号
                    contractNos.append(export.getCustomerContract()).append(" ");
                }
            }
            //将所有得到的数据封装进packing中 进行装箱
            packing.setGrossWeights(totalGrossWeight);
            packing.setNetWeights(totalNetWeight);
            packing.setTotalVolume(totalVolume);
            packing.setExportNos(contractNos.toString());
            packing.setExportIds(exportIds);
            packing.setPackingMoney(totalGrossWeight * 520);

        }
        return packing;
    }

    @Override
    public void save(Packing packing) {
        packing.setPackingListId(UUID.randomUUID().toString());
        //修改对应报运单的state属性，修改为3，即已装箱
        String exportIds = packing.getExportIds();
        if (exportIds != null) {
            changeExportState(exportIds, 3);
        }
        //设置state属性
        packing.setState(0);
        //将数据存入数据库
        packingDao.insertSelective(packing);
    }

    @Override
    public PageInfo<Packing> findByPage(PackingExample packingExample, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<Packing> packings = packingDao.selectByExample(packingExample);
        return new PageInfo<>(packings);
    }

    @Override
    public List<Packing> selectByExample(PackingExample example) {
        return null;
    }

    @Override
    public Packing selectByPrimaryKey(String packingListId) {
        return packingDao.selectByPrimaryKey(packingListId);
    }

    /**
     * 看传过来的export ids 能不能进行装箱
     *
     * @param exportIds
     * @return
     */
    @Override
    public Map<String, Object> checkAdd(String exportIds) {
        String[] exportIdsString = exportIds.split(",");
        Map<String, Object> map = new HashMap<>();
        if (exportIdsString.length == 1) {
            //说明只有一个 直接进行装箱
            toAddPacking(exportIds);
            map.put("success", true);
        } else {
            //说明有多个的 进行校验
            ExportExample exportExample = new ExportExample();
            exportExample.createCriteria().andIdIn(Arrays.asList(exportIdsString));
            List<List<String>> lists = exportDao.selectByExample(exportExample).stream().map(item -> {
                List<String> list = new ArrayList<>();
                list.add(item.getShipmentPort());
                list.add(item.getDestinationPort());
                list.add(item.getConsignee());
                return list;
            }).collect(Collectors.toList());
            boolean flag = true;
            List<String> firstList = lists.get(0);
            lists.removeIf(item -> item.equals(firstList));
            for (List<String> list : lists) {
                //遍历第一个参数判断 防止(东京->>>>北京   北京->>>>东京  contentAll方法失效)
                if (!firstList.get(0).equals(list.get(0))) {
                    flag = false;
                    break;
                }else {
                    flag = firstList.containsAll(list);
                }
                if (!flag) break;
            }
            if (flag) {
                map.put("success", true);
            } else {
                map.put("success", false);
                map.put("error", "请确保装箱老三样是相同的!");
            }
        }
        return map;
    }

    @Override
    public void delete(String packingListId) {
        Packing packing = packingDao.selectByPrimaryKey(packingListId);
        String exportIds = packing.getExportIds();
        if (exportIds != null) {
            //改变装箱单下报运单的state属性(修改为2) 已上报
            changeExportState(exportIds, 2);
        }
        //将委托单的数据删除
        packingDao.deleteByPrimaryKey(packingListId);
    }

    /**
     * 改变exports的状态为已报运
     */
    @Override
    public void changeExportState(String exportIds, int stateNum) {
        String[] exportIdArray = exportIds.split(",");
        List<String> exportIdList = Arrays.asList(exportIdArray);
        ExportExample exportExample = new ExportExample();
        exportExample.createCriteria().andIdIn(exportIdList);
        List<Export> exportList = exportDao.selectByExample(exportExample);
        if (exportList != null && exportIdList.size() > 0) {
            for (Export export : exportList) {
                //修改export的state值并在数据库中修改
                export.setState(stateNum);
                exportDao.updateByPrimaryKeySelective(export);
            }
        }
    }

    /**
     * 状态校验
     *
     * @param exportIds
     * @return
     */
    @Override
    public Map<String, Object> checkStatus(String exportIds) {
        Map<String, Object> map = new HashMap<>();
        String[] exportArray = exportIds.split(",");
        List<String> exportIdsList = Arrays.asList(exportArray);
        ExportExample exportExample = new ExportExample();
        exportExample.createCriteria().andIdIn(exportIdsList);
        Set<Integer> stateSet = exportDao.selectByExample(exportExample).stream().map(Export::getState).collect(Collectors.toSet());
        if (stateSet.size() > 1) {
            //说明有重复 (草稿 已报运等)
            map.put("success", false);
            map.put("error", "状态必须统一为已报运!");
        } else {
            //表示只有一个 校验
            if (stateSet.contains(2)) {
                map.put("success", true);
            } else {
                map.put("success", false);
                map.put("error", "状态必须统一为已报运!");
            }
        }
        return map;
    }
}